package com.tools;

import android.os.Build;
import android.support.annotation.RequiresApi;

import java.util.ArrayList;
import java.util.List;

import johnkkk.com.obj.ObjModel;

/**
 * @Author: clm
 * @Date: 2018-11-08
 */

public class ObjectGLConvertTools {
    public static final float[] arrayListToArray(List<Float> arrayList){
        float []f = new float[arrayList.size()];
        for(int i = 0;i < arrayList.size();i++){
            f[i] = arrayList.get(i);
        }
        return f;
    }

    /**
     * 将加载的obj原数据转为ObjMesh对象列表返回
     * @param objectLoader
     */
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    public static final List<ObjModel.ObjMesh> convertObjMesh(ObjectLoader objectLoader){
        List<ObjModel.ObjMesh> meshes = new ArrayList<>();
        for(ObjectLoader.ObjectGroup group : objectLoader.getGroupArray()){
            ArrayList<ObjectLoader.ObjectV> vList = new ArrayList<>();
            ArrayList<Float> vertexList = new ArrayList<>();
            ArrayList<Float> uvList = new ArrayList<>();
            ArrayList<Float> nList = new ArrayList<>();
            //取出构成当前组所有Face的位置数据，纹理数据和法线数据
            //然后构建局部索引
            for(ObjectLoader.ObjectF f : group.mF_List){
                //读取当前face位置数据
                for(Integer vi : f.mVIndexArray){
                    ObjectLoader.ObjectV v = objectLoader.getObjectVArray().get(vi);
                    if(!vList.contains(v)){
                        vList.add(v);
                        vertexList.add(v.x);
                        vertexList.add(v.y);
                        vertexList.add(v.z);
                    }
                }
                //读取当前face纹理数据
                for(Integer uvi : f.mVTIndexArray){
                    ObjectLoader.ObjectVT vt = objectLoader.getObjectVTArray().get(uvi);
                    uvList.add(vt.u);
                    uvList.add(vt.v);
                }
                //读取当前face法线数据
                for(Integer ni : f.mVNIndexArray){
                    ObjectLoader.ObjectVN vn = objectLoader.getObjectVNArray().get(ni);
                    nList.add(vn.x);
                    nList.add(vn.y);
                    nList.add(vn.z);
                }
            }
            //生成顶点属性和索引
            float vertex[] = arrayListToArray(vertexList);
            float uv[] = arrayListToArray(uvList);
            float n[] = arrayListToArray(nList);
            //一个面3个顶点
            //这里有一个要注意的是,索引是根据渲染的面数量来决定的
            //而面数量实际上等于纹理,法线数据量,但是不等于位置数据量
            //因为使用索引渲染时,根据当前索引值去位置数据,但是根据当前
            //索引的索引号取相应纹理,法线数据
            int index[] = new int[uv.length / 2];
            int j = 0;
            for(ObjectLoader.ObjectF f : group.mF_List){
                //读取当前face位置数据
                for(Integer vi : f.mVIndexArray){
                    ObjectLoader.ObjectV v = objectLoader.getObjectVArray().get(vi);
                    for(int i = 0;i < vList.size();i++){
                        if(vList.get(i).equals(v)){
                            index[j++] = i;
                            break;
                        }
                    }
                }
            }
            //生成网格
            meshes.add(new ObjModel.ObjMesh(vertex, uv, n, index, group.mMaterial));
        }
        return meshes;
    }


    /**
     * 将加载的obj原数据转为ObjMesh对象列表返回
     * @param objectLoader
     */
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    public static final List<ObjModel.ObjMesh> convertObjMesh2(ObjectLoader objectLoader){
        List<ObjModel.ObjMesh> meshes = new ArrayList<>();
        for(ObjectLoader.ObjectGroup group : objectLoader.getGroupArray()){
            ArrayList<ObjectLoader.ObjectV> vList = new ArrayList<>();
            ArrayList<Float> vertexList = new ArrayList<>();
            ArrayList<Float> uvList = new ArrayList<>();
            ArrayList<Float> nList = new ArrayList<>();
            //取出构成当前组所有Face的位置数据，纹理数据和法线数据
            //然后构建局部索引
            for(ObjectLoader.ObjectF f : group.mF_List){
                //读取当前face位置数据
                for(Integer vi : f.mVIndexArray){
                    ObjectLoader.ObjectV v = objectLoader.getObjectVArray().get(vi);
//                    if(!vList.contains(v)){
//                        vList.add(v);
//                    }
                    vertexList.add(v.x);
                    vertexList.add(v.y);
                    vertexList.add(v.z);
                }
                //读取当前face纹理数据
                for(Integer uvi : f.mVTIndexArray){
                    ObjectLoader.ObjectVT vt = objectLoader.getObjectVTArray().get(uvi);
                    uvList.add(vt.u);
                    uvList.add(vt.v);
                }
                //读取当前face法线数据
                for(Integer ni : f.mVNIndexArray){
                    ObjectLoader.ObjectVN vn = objectLoader.getObjectVNArray().get(ni);
                    nList.add(vn.x);
                    nList.add(vn.y);
                    nList.add(vn.z);
                }
            }
            //生成顶点属性和索引
            float vertex[] = arrayListToArray(vertexList);
            float uv[] = arrayListToArray(uvList);
            float n[] = arrayListToArray(nList);
            //一个面3个顶点
            //这里有一个要注意的是,索引是根据渲染的面数量来决定的
            //而面数量实际上等于纹理,法线数据量,但是不等于位置数据量
            //因为使用索引渲染时,根据当前索引值去位置数据,但是根据当前
            //索引的索引号取相应纹理,法线数据
            int index[] = new int[uv.length / 2];
            for(int i = 0;i < index.length;i++){
                index[i] = i;
            }
//            int j = 0;
//            for(ObjectLoader.ObjectF f : group.mF_List){
//                //读取当前face位置数据
//                for(Integer vi : f.mVIndexArray){
//                    ObjectLoader.ObjectV v = objectLoader.getObjectVArray().get(vi);
//                    for(int i = 0;i < vList.size();i++){
//                        if(vList.get(i).equals(v)){
//                            index[j++] = i;
//                            break;
//                        }
//                    }
//                }
//            }
            //生成网格
            meshes.add(new ObjModel.ObjMesh(vertex, uv, n, index, group.mMaterial));
        }
        return meshes;
    }
}
